#include <bsl_err.h>
#include <bsl_sal.h>
#include <crypt_algid.h>
#include <eal_md_local.h>
#include <crypt_eal_md.h>
#include <crypt_eal_provider.h>
#include <crypt_errno.h>
#include <crypt_sm3.h>

#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <cmocka.h>

#include "helper.h"

#define GROUP_TEST_MAX 100

#define SHA2_OUTPUT_MAXSIZE 100

typedef struct {
    int32_t id;
    char *in;
    char *out;
} CRYPT_SHA2_Test;

typedef struct {
    int32_t id;
    char *dataA;
    char *dataB;
    char *dataC;
    char *hash;
} CRYPT_SHA2_MultiData;

static int32_t SHA2_AlgID[] = {
    CRYPT_MD_SHA224,
    CRYPT_MD_SHA256,
    CRYPT_MD_SHA384,
    CRYPT_MD_SHA512,
};

static CRYPT_EAL_LibCtx *CreateLoadLibCtx()
{
    CRYPT_EAL_LibCtx *libctx = CRYPT_EAL_LibCtxNew();
    assert_non_null(libctx);
    assert_int_equal(CRYPT_EAL_ProviderSetLoadPath(libctx, "../../build"), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_ProviderLoad(libctx, BSL_SAL_LIB_FMT_LIBSO, "kae_provider", NULL, NULL), CRYPT_SUCCESS);
    return libctx;
}

static void SDV_KAE_SHA2_PROVIDER_LOAD(void **state)
{
    (void)state;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_SHA2_API_TC001(void **state)
{
    (void)state;

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();

    CRYPT_EAL_MdCTX *ctx = NULL;

    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, -1, "provider=kaev1");
    assert_null(ctx);

    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, CRYPT_MD_MAX, "provider=kaev1");
    assert_null(ctx);

    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, CRYPT_MD_SHA224, "provider=kaev1");
    assert_non_null(ctx);
    CRYPT_EAL_MdFreeCtx(ctx);

    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, CRYPT_MD_SHA256, "provider=kaev1");
    assert_non_null(ctx);
    CRYPT_EAL_MdFreeCtx(ctx);

    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, CRYPT_MD_SHA384, "provider=kaev1");
    assert_non_null(ctx);
    CRYPT_EAL_MdFreeCtx(ctx);

    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, CRYPT_MD_SHA512, "provider=kaev1");
    assert_non_null(ctx);
    CRYPT_EAL_MdFreeCtx(ctx);

    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_SHA2_API_TC002(void **state)
{
    int32_t id = *(int32_t *)(*state);

    CRYPT_EAL_MdCTX *ctx = NULL;

    assert_int_equal(CRYPT_EAL_MdDeinit(ctx), CRYPT_NULL_INPUT);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, id, "provider=kaev1");
    assert_non_null(ctx);

    uint8_t input[SHA2_OUTPUT_MAXSIZE];
    const uint32_t inLen = SHA2_OUTPUT_MAXSIZE;

    uint8_t out[SHA2_OUTPUT_MAXSIZE];
    uint32_t validOutLen = CRYPT_EAL_MdGetDigestSize(id);
    uint32_t invalidOutLen = validOutLen - 1;

    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_EAL_ERR_STATE);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, out, &validOutLen), CRYPT_EAL_ERR_STATE);

    assert_int_equal(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_MdUpdate(NULL, input, inLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, NULL, inLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_MdFinal(NULL, out, &validOutLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, NULL, &validOutLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, out, NULL), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, out, &invalidOutLen), CRYPT_EAL_BUFF_LEN_NOT_ENOUGH);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, out, &validOutLen), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdGetId(ctx), id);
    assert_int_equal(CRYPT_EAL_MdDeinit(ctx), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdIsValidAlgId(id), true);

    assert_int_equal(CRYPT_EAL_MdDeinit(ctx), CRYPT_SUCCESS);

    CRYPT_EAL_MdFreeCtx(ctx);
    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_SHA2_FUNC_TC001(void **state)
{
    int32_t id = *(int32_t *)(*state);

    CRYPT_EAL_MdCTX *ctx1 = NULL;
    CRYPT_EAL_MdCTX *ctx2 = NULL;

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx1 = CRYPT_EAL_ProviderMdNewCtx(libctx, id, "provider=kaev1");
    assert_non_null(ctx1);

    ctx2 = CRYPT_EAL_ProviderMdNewCtx(libctx, id, "provider=kaev1");
    assert_non_null(ctx2);

    uint8_t input[5050];
    uint32_t inLenTotal = 0;
    uint32_t inLenBase;
    uint8_t out1[SHA2_OUTPUT_MAXSIZE];
    uint8_t out2[SHA2_OUTPUT_MAXSIZE];
    uint32_t outLen = CRYPT_EAL_MdGetDigestSize(id);

    assert_int_equal(CRYPT_EAL_MdInit(ctx1), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdInit(ctx2), CRYPT_SUCCESS);

    for (inLenBase = 1; inLenBase <= 100; inLenBase++) {
        assert_int_equal(CRYPT_EAL_MdUpdate(ctx1, input + inLenTotal, inLenBase), CRYPT_SUCCESS);
        inLenTotal += inLenBase;
    }
    assert_int_equal(CRYPT_EAL_MdFinal(ctx1, out1, &outLen), CRYPT_SUCCESS);

    outLen = CRYPT_EAL_MdGetDigestSize(id);
    assert_int_equal(CRYPT_EAL_MdUpdate(ctx2, input, inLenTotal), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx2, out2, &outLen), CRYPT_SUCCESS);

    outLen = CRYPT_EAL_MdGetDigestSize(id);
    assert_memory_equal(out1, out2, outLen);

    CRYPT_EAL_MdFreeCtx(ctx1);
    CRYPT_EAL_MdFreeCtx(ctx2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_SHA2_Test SDV_KAE_SHA2_FUNC_TC002_VEC[] = {
    {CRYPT_MD_SHA224, NULL, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"},
    {CRYPT_MD_SHA256, NULL, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
    {CRYPT_MD_SHA384, NULL,
     "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"},
    {CRYPT_MD_SHA512, NULL,
     "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"},
};

static void SDV_KAE_SHA2_FUNC_TC002(void **state)
{
    CRYPT_SHA2_Test *test = (CRYPT_SHA2_Test *)*state;
    int32_t id = test->id;
    Hex *digest = NewHex();
    assert_int_equal(ConvertHex(test->out, digest), 0);

    CRYPT_EAL_MdCTX *ctx = NULL;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, id, "provider=kaev1");
    assert_non_null(ctx);

    uint8_t out[SHA2_OUTPUT_MAXSIZE];
    uint32_t outLen = CRYPT_EAL_MdGetDigestSize(id);

    assert_int_equal(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS);
    assert_memory_equal(out, digest->x, digest->len);

    FreeHex(digest);

    CRYPT_EAL_MdFreeCtx(ctx);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_SHA2_Test SDV_KAE_SHA2_FUNC_TC003_VEC[] = {
    {CRYPT_MD_SHA224, "", "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"},
    {CRYPT_MD_SHA224, "84", "3cd36921df5d6963e73739cf4d20211e2d8877c19cff087ade9d0e3a"},
    {CRYPT_MD_SHA224, "a4bc10b1a62c96d459fbaf3a5aa3face73", "d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1"},
    {CRYPT_MD_SHA224,
     "a8e729d336d5d6ac50e1e22f0b193b66e26042fc6459214129875e740ab2b142918c138aaf941863ad3b7e6065450613b273",
     "452bf2e5ebfc4e451cc434bc09e2a10032eed0b7627cf55e7e5ed0e2"},
    {CRYPT_MD_SHA256, "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
    {CRYPT_MD_SHA256, "d3", "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"},
    {CRYPT_MD_SHA256, "1b503fb9a73b16ada3fcf1042623ae7610",
     "d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509"},
    {CRYPT_MD_SHA256,
     "3d83df37172c81afd0de115139fbf4390c22e098c5af4c5ab4852406510bc0e6cf741769f44430c5270fdae0cb849d71cbab",
     "99dc772e91ea02d9e421d552d61901016b9fd4ad2df4a8212c1ec5ba13893ab2"},
    {CRYPT_MD_SHA384, "",
     "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"},
    {CRYPT_MD_SHA384, "c5",
     "b52b72da75d0666379e20f9b4a79c33a329a01f06a2fb7865c9062a28c1de860ba432edfd86b4cb1cb8a75b46076e3b1"},
    {CRYPT_MD_SHA384, "bb84a014cd17cc232c98ae8b0709917e9d",
     "85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263"},
    {CRYPT_MD_SHA384,
     "f7b577f1396b23c27eb637e53d3d92460270b001cc612fd3b4d68bcdd09c2d50571ea4350636324cc2428a087e7bd8785f82",
     "80afe111e44ad9aff9e39c4cf9e6b4c520072b4550e62b1740160a04f8d530612dc098917a556b44977d0e73df518bee"},
    {CRYPT_MD_SHA512, "",
     "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"},
    {CRYPT_MD_SHA512, "21",
     "3831a6a6155e509dee59a7f451eb35324d8f8f2df6e3708894740f98fdee23889f4de5adb0c5010dfb555cda77c8ab5dc902094c52de3278f35a75ebc25f093a"},
    {CRYPT_MD_SHA512, "6ba004fd176791efb381b862e298c67b08",
     "112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe"},
    {CRYPT_MD_SHA512,
     "317e5d9ac73ed0633fa18ebebbca7909ec3a5ef790478f9c38cacec44f196d895835b425774483043341381e7af2d383e51a",
     "b10bb04491b9c0c334709b407cda1d503efb6b63ee944f2d366b6855e6e63e5b80115be4be7ff63edecdfb5923792e68123976d79212b3884dec2179d1fcf382"},
};

static void SDV_KAE_SHA2_FUNC_TC003(void **state)
{
    CRYPT_SHA2_Test *test = (CRYPT_SHA2_Test *)*state;

    int32_t algId = test->id;
    Hex *in = NewHex();
    Hex *digest = NewHex();

    assert_int_equal(ConvertHex(test->in, in), 0);
    assert_int_equal(ConvertHex(test->out, digest), 0);

    CRYPT_EAL_MdCTX *ctx = NULL;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, algId, "provider=kaev1");
    assert_non_null(ctx);

    uint8_t out[SHA2_OUTPUT_MAXSIZE];
    uint32_t outLen = CRYPT_EAL_MdGetDigestSize(algId);

    assert_int_equal(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, in->x, in->len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS);

    assert_memory_equal(out, digest->x, digest->len);

    FreeHex(in);
    FreeHex(digest);

    CRYPT_EAL_MdFreeCtx(ctx);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_SHA2_MultiData SDV_KAE_SHA2_FUNC_TC004_VEC[] = {
    {CRYPT_MD_SHA224, "a4bc10", "", "b1a62c96d459fbaf3a5aa3face73",
     "d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1"},
    {CRYPT_MD_SHA224, "a8e7", "29d336d5d6ac50",
     "e1e22f0b193b66e26042fc6459214129875e740ab2b142918c138aaf941863ad3b7e6065450613b273",
     "452bf2e5ebfc4e451cc434bc09e2a10032eed0b7627cf55e7e5ed0e2"},
    {CRYPT_MD_SHA256, "1b503fb9a73b16ada3fcf1042623", "", "ae7610",
     "d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509"},
    {CRYPT_MD_SHA256, "3d83df37",
     "172c81afd0de115139fbf4390c22e098c5af4c5ab4852406510bc0e6cf741769f44430c5270fdae0cb849d", "71cbab",
     "99dc772e91ea02d9e421d552d61901016b9fd4ad2df4a8212c1ec5ba13893ab2"},
    {CRYPT_MD_SHA384, "bb84", "", "a014cd17cc232c98ae8b0709917e9d",
     "85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263"},
    {CRYPT_MD_SHA384, "f7b577f139", "6b23c27e",
     "b637e53d3d92460270b001cc612fd3b4d68bcdd09c2d50571ea4350636324cc2428a087e7bd8785f82",
     "80afe111e44ad9aff9e39c4cf9e6b4c520072b4550e62b1740160a04f8d530612dc098917a556b44977d0e73df518bee"},
    {CRYPT_MD_SHA512, "6ba004fd17", "", "6791efb381b862e298c67b08",
     "112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe"},
    {CRYPT_MD_SHA512, "317e5d9ac73ed0",
     "633fa18ebebbca7909ec3a5ef790478f9c38cacec44f196d895835b425774483043341381e7af2", "d383e51a",
     "b10bb04491b9c0c334709b407cda1d503efb6b63ee944f2d366b6855e6e63e5b80115be4be7ff63edecdfb5923792e68123976d79212b3884dec2179d1fcf382"},
};

static void SDV_KAE_SHA2_FUNC_TC004(void **state)
{
    CRYPT_SHA2_MultiData *test = (CRYPT_SHA2_MultiData *)*state;

    int32_t algId = test->id;
    Hex *data1 = NewHex();
    Hex *data2 = NewHex();
    Hex *data3 = NewHex();
    Hex *hash = NewHex();

    assert_int_equal(ConvertHex(test->dataA, data1), 0);
    assert_int_equal(ConvertHex(test->dataB, data2), 0);
    assert_int_equal(ConvertHex(test->dataC, data3), 0);
    assert_int_equal(ConvertHex(test->hash, hash), 0);

    unsigned char output[SHA2_OUTPUT_MAXSIZE];
    uint32_t outLen = SHA2_OUTPUT_MAXSIZE;

    CRYPT_EAL_MdCTX *ctx = NULL;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, algId, "provider=kaev1");
    assert_non_null(ctx);

    assert_int_equal(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, data1->x, data1->len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, data2->x, data2->len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdUpdate(ctx, data3->x, data3->len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdFinal(ctx, output, &outLen), CRYPT_SUCCESS);

    assert_memory_equal(output, hash->x, hash->len);

    FreeHex(data1);
    FreeHex(data2);
    FreeHex(data3);
    FreeHex(hash);

    CRYPT_EAL_MdFreeCtx(ctx);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_SHA2_Test SDV_KAE_SHA2_DUP_FUNC_TC001_VEC[] = {
    {CRYPT_MD_SHA224, "a4bc10b1a62c96d459fbaf3a5aa3face73", "d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1"},
    {CRYPT_MD_SHA256, "1b503fb9a73b16ada3fcf1042623ae7610",
     "d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509"},
    {CRYPT_MD_SHA384, "bb84a014cd17cc232c98ae8b0709917e9d",
     "85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263"},
    {CRYPT_MD_SHA512, "6ba004fd176791efb381b862e298c67b08",
     "112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe"},
};

static void SDV_KAE_SHA2_DUP_FUNC_TC001(void **state)
{
    CRYPT_SHA2_Test *test = (CRYPT_SHA2_Test *)*state;

    int32_t id = test->id;
    Hex *msg = NewHex();
    Hex *hash = NewHex();

    assert_int_equal(ConvertHex(test->in, msg), 0);
    assert_int_equal(ConvertHex(test->out, hash), 0);

    CRYPT_EAL_MdCTX *dupCtx = NULL;
    CRYPT_EAL_MdCTX *ctx = NULL;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx = CRYPT_EAL_ProviderMdNewCtx(libctx, id, "provider=kaev1");
    assert_non_null(ctx);

    uint8_t output[SHA2_OUTPUT_MAXSIZE];
    uint32_t outLen = SHA2_OUTPUT_MAXSIZE;

    dupCtx = CRYPT_EAL_MdDupCtx(ctx);
    assert_non_null(dupCtx);

    assert_int_equal(CRYPT_EAL_MdInit(dupCtx), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdUpdate(dupCtx, msg->x, msg->len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_MdFinal(dupCtx, output, &outLen), CRYPT_SUCCESS);
    assert_int_equal(memcmp(output, hash->x, hash->len), 0);

    FreeHex(msg);
    FreeHex(hash);

    CRYPT_EAL_MdFreeCtx(ctx);
    CRYPT_EAL_MdFreeCtx(dupCtx);
    CRYPT_EAL_LibCtxFree(libctx);
}

int main(void)
{
    struct CMUnitTest CMSHA2_TEST[GROUP_TEST_MAX] = {NULL};
    int testCnt = 0;

    CMSHA2_TEST[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_SHA2_PROVIDER_LOAD);
    CMSHA2_TEST[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_SHA2_API_TC001);

    for (size_t i = 0; i < sizeof(SHA2_AlgID) / sizeof(SHA2_AlgID[0]); i++) {
        CMSHA2_TEST[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_SHA2_FUNC_TC001, &SHA2_AlgID[i]);
    }

    for (size_t i = 0; i < sizeof(SHA2_AlgID) / sizeof(SHA2_AlgID[0]); i++) {
        CMSHA2_TEST[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_SHA2_API_TC002, &SHA2_AlgID[i]);
    }

    for (size_t i = 0; i < sizeof(SDV_KAE_SHA2_FUNC_TC002_VEC) / sizeof(SDV_KAE_SHA2_FUNC_TC002_VEC[0]); i++) {
        CMSHA2_TEST[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_SHA2_FUNC_TC002, &SDV_KAE_SHA2_FUNC_TC002_VEC[i]);
    }

    for (size_t i = 0; i < sizeof(SDV_KAE_SHA2_FUNC_TC003_VEC) / sizeof(SDV_KAE_SHA2_FUNC_TC003_VEC[0]); i++) {
        CMSHA2_TEST[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_SHA2_FUNC_TC003, &SDV_KAE_SHA2_FUNC_TC003_VEC[i]);
    }

    for (size_t i = 0; i < sizeof(SDV_KAE_SHA2_FUNC_TC004_VEC) / sizeof(SDV_KAE_SHA2_FUNC_TC004_VEC[0]); i++) {
        CMSHA2_TEST[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_SHA2_FUNC_TC004, &SDV_KAE_SHA2_FUNC_TC004_VEC[i]);
    }

    for (size_t i = 0; i < sizeof(SDV_KAE_SHA2_DUP_FUNC_TC001_VEC) / sizeof(SDV_KAE_SHA2_DUP_FUNC_TC001_VEC[0]); i++) {
        CMSHA2_TEST[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_SHA2_DUP_FUNC_TC001,
                                                                              &SDV_KAE_SHA2_DUP_FUNC_TC001_VEC[i]);
    }

    cmocka_run_group_tests(CMSHA2_TEST, NULL, NULL);
    return 0;
}